//
//  NSObject+Mapping.m
//  Y2NetWorking
//
//  Created by ycgame on 2020/11/24.
//

#import "NSObject+Y2Mapping.h"
#import <objc/runtime.h>

const char *kY2ObjectPropertyListKey = "Y2ObjectPropertyListKey";

@implementation NSObject (Y2Mapping)

+ (instancetype)y2ObjectWithKeyValues:(NSDictionary *)dict {
    id object = [[self alloc] init];
    
    unsigned int count = 0;
    
    Ivar *ivarList = class_copyIvarList(self, &count);
    
    for (int i = 0; i < count; i++) {
        // 获取成员属性
        Ivar ivar = ivarList[i];
        // 获取属性名
        NSString *ivarName = [NSString stringWithUTF8String:ivar_getName(ivar)];
        // 获取成员属性类型
        NSString *ivarType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        // 成员属性名
        NSString *key = [ivarName substringFromIndex:1];
        
        // 去字典中取出对应value给模型属性赋值
        id value;
        // 判断对象是否实现替换属性名方法
        SEL replacedSel = NSSelectorFromString(@"y2ReplacedKeyFromPropertyName");
        if ([object respondsToSelector:replacedSel]) {
            IMP imp = [object methodForSelector:replacedSel];
            id (*func)(NSDictionary *, SEL) = (void *)imp;
            NSDictionary *classDict = func(object, replacedSel);
            NSString *dictKey = classDict[key];
            if (dictKey) {
                value = dict[dictKey];
            } else {
                value = dict[key];
            }
        } else {
            value = dict[key];
        }
        
        // value为字典，且object对应属性属性不为NS类
        if ([value isKindOfClass:[NSDictionary class]] && ![ivarType containsString:@"NS"]) {
            ivarType = [ivarType stringByReplacingOccurrencesOfString:@"@" withString:@""];
            ivarType = [ivarType stringByReplacingOccurrencesOfString:@"\"" withString:@""];
            Class subClass = NSClassFromString(ivarType);
            if (subClass) {
                value = [subClass y2ObjectWithKeyValues:value];
            }
        }
        
        // 数组
        if ([value isKindOfClass:[NSArray class]]) {
            // 如果实现数组对象方法
            SEL sel = NSSelectorFromString(@"y2ObjectClassInArray");
            if ([object respondsToSelector:sel]) {
                IMP imp = [object methodForSelector:sel];
                id (*func)(NSDictionary *, SEL) = (void *)imp;
                NSDictionary *classDict = func(object, sel);
                NSString *type = classDict[key];
                // 如果没找到type，直接跳出
                if (!type) { continue; }
                
                Class subClass = NSClassFromString(type);
                NSMutableArray *subList = [NSMutableArray arrayWithCapacity:[value count]];
                for (NSDictionary *dic in value) {
                    id obj = [subClass y2ObjectWithKeyValues:dic];
                    [subList addObject:obj];
                }
                value = subList;
            }
        }
        
        if (value) {
            [object setValue:value forKey:key];
        }
    }
    
    return object;
}

- (void)setValue:(id)value forUndefinedKey:(NSString *)key { }

@end
